package com.gitee.wsl.ext.array

import com.gitee.wsl.base.Tuple2
import com.gitee.wsl.func.predicate.Predicate


fun ByteArray.splitLines(): List<ByteArray> {
    if (this.isEmpty()) return listOf()
    val lines = arrayListOf<ByteArray>()
    var lastSplit = 0
    var skip = 0
    for ((i, byte) in this.withIndex()) {
        if (skip > 0) {
            skip--
            continue
        }
        if (byte == '\n'.code.toByte()) {
            lines.add(this.sliceArray(lastSplit..<i))
            lastSplit = i + 1
        } else if (byte == '\r'.code.toByte() && i + 1 < this.size && this[i + 1] == '\n'.code.toByte()) {
            skip = 1
            lines.add(this.sliceArray(lastSplit..<i))
            lastSplit = i + 2
        } else if (byte == '\r'.code.toByte()) {
            lines.add(this.sliceArray(lastSplit..<i))
            lastSplit = i + 1
        }
    }
    lines += this.sliceArray(lastSplit..<this.size)
    return lines
}

fun ByteArray.split(delimiter: ByteArray): List<ByteArray> {
    val lines = arrayListOf<ByteArray>()
    var lastSplit = 0
    var skip = 0
    for (i in indices) {
        if (skip > 0) {
            skip--
            continue
        }
        if (this.sliceArray(i..<i + delimiter.size).toList() == delimiter.toList()) {
            skip = delimiter.size
            lines += this.sliceArray(lastSplit..<i)
            lastSplit = i + delimiter.size
        }
    }
    lines += this.sliceArray(lastSplit..<this.size)
    return lines
}


fun <T> Array<T>.splitAt(predicate: Predicate< T>): Tuple2<List<T>, List<T>> {
    val neg= predicate.negate()
    val init = takeWhile { neg.test(it)}
    return init to drop(init.size)
}